<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<HTML>
<HEAD>
<TITLE>No title</TITLE><LINK REL=home HREF="Title.html">
<LINK REL=index HREF="DocIndex.html">
<LINK REL=previous HREF="Title.html">
<LINK REL=next HREF="DocIndex.html">
<STYLE type="text/css">
/* Style sheet for SWI-Prolog latex2html
*/

dd.defbody
{ margin-bottom: 1em;
}

dt.pubdef
{ background-color: #c5e1ff;
}

.bib dd
{ margin-bottom: 1em;
}

.bib dt
{ float: left;
margin-right: 1.3ex;
}

pre.code
{ margin-left: 1.5em;
margin-right: 1.5em;
border: 1px dotted;
padding-top: 5px;
padding-left: 5px;
padding-bottom: 5px;
background-color: #f8f8f8;
}

div.navigate
{ text-align: center;
background-color: #f0f0f0;
border: 1px dotted;
padding: 5px;
}

div.title
{ text-align: center;
padding-bottom: 1em;
font-size: 200%;
font-weight: bold;
}

div.author
{ text-align: center;
font-style: italic;
}

div.abstract
{ margin-top: 2em;
background-color: #f0f0f0;
border: 1px dotted;
padding: 5px;
margin-left: 10%; margin-right:10%;
}

div.abstract-title
{ text-align: center;
padding: 5px;
font-size: 120%;
font-weight: bold;
}

div.toc-h1
{ font-size: 200%;
font-weight: bold;
}

div.toc-h2
{ font-size: 120%;
font-weight: bold;
margin-left: 2em;
}

div.toc-h3
{ font-size: 100%;
font-weight: bold;
margin-left: 4em;
}

div.toc-h4
{ font-size: 100%;
margin-left: 6em;
}

span.sec-nr
{ 
}

span.sec-title
{ 
}

span.pred-ext
{ font-weight: bold;
}

span.pred-tag
{ float: right;
font-size: 80%;
font-style: italic;
color: #202020;
}

/* Footnotes */

sup.fn { color: blue; text-decoration: underline; }
span.fn-text { display: none; }
sup.fn span {display: none;}
sup:hover span 
{ display: block !important;
position: absolute; top: auto; left: auto; width: 80%;
color: #000; background: white;
border: 2px solid;
padding: 5px; margin: 10px; z-index: 100;
font-size: smaller;
}
</STYLE>
</HEAD>

<BODY>
<DIV class="navigate"><A class="nav" href="Title.html">Home</A>
<A class="nav" href="DocIndex.html">Index</A>
<A class="nav" href="Title.html">Previous</A>
<A class="nav" href="DocIndex.html">Next</A>
</DIV>

<H2><A NAME="sec:1"><SPAN class="sec-nr">1</SPAN> <SPAN class="sec-title">theory.pl 
-- theory: music theory reasoning in prolog</SPAN></A></H2>

<P><A NAME="sec:theory"></A>

<DL>
<DT><B>author</B><DD> Erik Flister erik.flister@gmail.com
<DT><B>version</B><DD> 0.5 (alpha - implemented predicates tested and 
trusted)
<DT><B>See also</B><DD>
<UL>
<LI><A class="url" href="http://code.google.com/p/mingus/">mingus</A> 
(music theory library in python)
<LI><A class="url" href="http://www.biology.ucsd.edu/labs/reinagel/eflister/">pyBass</A> 
(python realtime jazz improviser that uses pyPortMidi and <CODE>theory.pl</CODE> 
via pyswip)
<LI><A class="url" href="http://www.mitpressjournals.org/doi/pdf/10.1162/014892699559977">Music 
Theory Workbench</A> (automated common practice harmony analysis)
<LI>references :
<UL>
<LI>harmony books
<UL>
<LI><A class="url" href="http://www.amazon.com/Harmony-Voice-Leading-Edward-Aldwell/dp/0155062425">aldwell 
and schachter</A> the authority
<LI><A class="url" href="http://www.amazon.com/Harmony-Context-Miguel-Roig-Francoli/dp/0072938595/ref=sr_1_1?ie=UTF8&s=books&qid=1232038418&sr=1-1">roig-francoli</A> 
also good, includes counterpoint
<LI><A class="url" href="http://www.amazon.com/Jazz-Theory-Book-Mark-Levine/dp/1883217040/ref=pd_bxgy_b_img_b">levine</A> 
jazz
</UL>
<LI>wikipedia
<UL>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Tonality">tonality</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Harmony">harmony</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Diatonic_function">diatonic 
function</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Figured_bass">figured 
bass</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Counterpoint">species 
counterpoint</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Chord_(music)">chord</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Tonnetz">tonnetz</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Music_and_mathematics">music 
and mathematics</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Pitch_space">pitch 
space</A>]
<LI><A class="url" href="http://en.wikipedia.org/wiki/Musical_set_theory">musical 
set theory</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Diatonic_set_theory">diatonic 
set theory</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Consonance_and_dissonance">consonance 
and dissonance</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Limit_(music)">limit</A>
<UL>
<LI>key insight: "Harry Partch, Ivor Darreg, and Ralph David Hill are 
among the many microtonalists to suggest that music has been slowly 
evolving to employ higher and higher harmonics in its constructs. In 
medieval music, only chords made of octaves and perfect fifths 
(involving relationships among the first 3 harmonics) were considered 
consonant. In the West, triadic harmony sprang up around the time of the 
Renaissance, and triads quickly became the fundamental building blocks 
of Western music. The major and minor thirds of these triads invoke 
relationships among the first 5 harmonics. Around the turn of the 20th 
century, tetrads debuted as fundamental building blocks in 
African-American music. In conventional music theory pedagogy, these 
tetrads are usually explained as chains of major and minor thirds. 
However, they can also be explained as coming directly from 
relationships among harmonics greater than 5. For example, the dominant 
7th chord in 12-ET approximates 4:5:6:7, while the Major 7th chord 
approximates 8:10:12:15. This story is suggestive of evolution through a 
regime of punctuated equilibria, wherein the predominant technology of 
each epoch (e.g. triads) almost completely replaces that of previous 
epochs..."
</UL>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Harmonic_major_scale">harmonic 
major scale</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Jazz_scales">jazz 
scales</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Coherence_(music_theory)">scale 
coherence</A>
</UL>
<LI><A class="url" href="http://www.andymilne.dial.pipex.com/Scales.shtml">http://www.andymilne.dial.pipex.com/Scales.shtml</A> 
defines proper and prime scales, nondiatonic theories, etc.
<UL>
<LI>melodic smoothness: proper means that no interval of degree N in a 
scale is smaller than an interval of degree M<VAR>&lt;</VAR>N
<LI>harmonic utility: prime means that every note is part of at least 
one major or minor third, and no note has both a major and minor third 
(possibly equivalent to no chromatic semitones - eg both c and c#)
<UL>
<LI>there are only 5 prime scales, all heptatonicgiven 12 note octaves - 
major, harmonic minor, melodic minor, harmonic major, double harmonic
</UL>
</UL>
<LI><A class="url" href="http://tonalsoft.com/enc/encyclopedia.aspx">microtonal 
theory</A>
<LI>tymoczko geometery of voice leading papers
<UL>
<LI><A class="url" href="http://www.sciencemag.org/cgi/content/full/313/5783/72">http://www.sciencemag.org/cgi/content/full/313/5783/72</A>
<LI><A class="url" href="http://www.sciencemag.org/cgi/content/full/320/5874/328">http://www.sciencemag.org/cgi/content/full/320/5874/328</A>
<LI><A class="url" href="http://www.sciencemag.org/cgi/content/full/sci;320/5874/346">http://www.sciencemag.org/cgi/content/full/sci;320/5874/346</A>
</UL>
<LI>pachet and roy papers on constraint logic programming for common 
practice harmony
<UL>
<LI><A class="url" href="http://www.csl.sony.fr/downloads/papers/2000/pachet-constraints2000.pdf">http://www.csl.sony.fr/downloads/papers/2000/pachet-constraints2000.pdf</A> 
review
<LI><A class="url" href="http://www-poleia.lip6.fr/~fdp/MyPapers/BackTalk/ES95.final.ps.Z">http://www-poleia.lip6.fr/~fdp/MyPapers/BackTalk/ES95.final.ps.Z</A>
<LI><A class="url" href="http://www-poleia.lip6.fr/~fdp/MyPapers/BackTalk/contraintes-tools95.ps.Z">http://www-poleia.lip6.fr/~fdp/MyPapers/BackTalk/contraintes-tools95.ps.Z</A>
</UL>
</UL>
</UL>
<DT><B>Compatibility</B><DD>
<UL>
<LI>i test/run with osx 10.5.6, python 2.6, pyPortMidi 0.0.3, pyrex 
0.9.8.5, portmidi 82, pyswip 0.2.2, swipl 5.7, lilypond 2.12.1, PIL 
1.1.6
<LI>trying the betas of <A class="url" href="http://www.swi-prolog.org/packages/pldoc.html">pldoc</A> 
(documentation) and <A class="url" href="http://www.swi-prolog.org/packages/plunit.html">plunit</A> 
(unit testing), which are swipl native but somewhat generally 
compatible?
<LI>swipl (common libraries used, likely almost compatible in most 
prologs: apply, debug, lists, pairs, aggregate). output of <SPAN class="pred-ext">check/0</SPAN> 
catches some, but not all library usages.
</UL>
<DT><B>copyright</B><DD> Erik Flister
<DT><B>license</B><DD> GPL
<DT><B>bug</B><DD>
<UL>
<LI>voiceLeadingOK seems to sometimes allow simultaneous jumps greater 
than a third in more than 1 voice. i think this is because it doesn't 
realize that <A class="pred" href="theory.html#interval/2">interval/2</A> 
omits non-existent intervals like doulbe-augmented-fifths (eg btw c and 
gx)
<LI><A class="pred" href="theory.html#conforms/2">conforms/2</A> does 
not enforce minimum requirements!
</UL>
<DT><B>To be done</B><DD>
<UL>
<LI>voicing needs to disallow R333, RR33, and R337 (ie strictly more 
roots than anything else when 5th omitted)
<LI>find best key sig -- one with fewest accidentals and fewest 
violations. if still need resolution, prefer flats. this suggests a 
tonic (how determine mode?)...
<LI>still more doc to write
<LI>functional progressions
<LI>cadences
<LI>dissonance handling in voice leading
<LI>find static solution to complete voiceleading transition matrix -- 
30k<VAR>/\</VAR>2 but sparse, takes about 4 sec per voicing to check the 
other 30k, so that's only 33 hours of computation, can save with 
qsave_program. add visualization/navigation to the GUI that projects 4D 
chord vectors to 2D space, with directed arcs at allowed transitions -- 
grey out those that are not state compatible (due to jumps/dissonances 
waiting for resolution)
<LI>input of scores w/harmony error detection
<LI>include functions/figured bass/chord symbols in output to 
pyswip/lilypond
<LI>extended chords
<LI>species couterpoint
<LI>proper/prime scales + theories on prime scales
<LI>switch to clp(fd)
<UL>
<LI>this is the finite domain constraint solver, which defines <SPAN class="pred-ext">#=/2</SPAN> 
and <SPAN class="pred-ext">#&lt;/2</SPAN>, etc, bidirectional 
replacements for <SPAN class="pred-ext">is/2</SPAN> and <SPAN class="pred-ext">&lt;/2</SPAN>, 
so it can more quickly eliminate most integers from consideration.
<LI><A class="url" href="http://gollem.science.uva.nl/SWI-Prolog/Manual/clpfd.html">docs</A>
<LI><A class="url" href="http://gollem.science.uva.nl/SWI-Prolog/mailinglist/archive/2008/q1/0147.html">best 
concrete english description i've seen</A>
<LI><A class="url" href="http://en.wikipedia.org/wiki/Constraint_logic_programming">wikipedia</A>
<LI><A class="url" href="http://kti.ms.mff.cuni.cz/~bartak/constraints/index.html">bartak's 
guide</A>
</UL>
<LI>redefine terms using library(record) to get named access to fields 
and library(error)/DCG's to do type checking
<LI>remove <SPAN class="pred-ext">append/3</SPAN>'s (any other bad 
style?)
</UL>
</DL>

<P>this prolog module defines predicates for reasoning about music 
theoretical concepts such as notes, scales, modes, intervals, chords, 
species counterpoint, figured bass, functional progressions, and voice 
leading. it is designed to work with a front-end GUI in python with 
realtime midi output.

<H4><A NAME="sec:1.1"><SPAN class="sec-nr">1.1</SPAN> <SPAN class="sec-title">predicate 
directory</SPAN></A></H4>

<P><B>hardcoded constants</B>
<BLOCKQUOTE>
<A class="pred" href="theory.html#numNotesPerOctave/1">numNotesPerOctave/1</A>
<A class="pred" href="theory.html#whiteKeys/1">whiteKeys/1</A>
<A class="pred" href="theory.html#accidentals/1">accidentals/1</A>
<A class="pred" href="theory.html#intervalNamesTypes/1">intervalNamesTypes/1</A>
<A class="pred" href="theory.html#intervalQualities/2">intervalQualities/2</A>
<A class="pred" href="theory.html#chordQuality/2">chordQuality/2</A>
<A class="pred" href="theory.html#chordQuality/3">chordQuality/3</A>
<A class="pred" href="theory.html#chordInversion/2">chordInversion/2</A>
<A class="pred" href="theory.html#scaleName/2">scaleName/2</A>
<A class="pred" href="theory.html#modeName/3">modeName/3</A>
<A class="pred" href="theory.html#octaveBreaks/1">octaveBreaks/1</A>
<A class="pred" href="theory.html#voice/3">voice/3</A>
<A class="pred" href="theory.html#refNoteNum/2">refNoteNum/2</A>
<A class="pred" href="theory.html#consonant/1">consonant/1</A>
<A class="pred" href="theory.html#functions/1">functions/1</A>
</BLOCKQUOTE>

<P><B>predicates dynamically generated from the constants and cached out 
to ground for fast search</B>
<BLOCKQUOTE>
<A class="pred" href="theory.html#accidental/2">accidental/2</A>
<A class="pred" href="theory.html#whiteKey/2">whiteKey/2</A>
<A class="pred" href="theory.html#chroma/1">chroma/1</A>
<A class="pred" href="theory.html#octaveRange/2">octaveRange/2</A>
<A class="pred" href="theory.html#note/1">note/1</A>
<A class="pred" href="theory.html#noteNum/2">noteNum/2</A>
<A class="pred" href="theory.html#intervalQuality/3">intervalQuality/3</A>
<A class="pred" href="theory.html#interval/1">interval/1</A>
<A class="pred" href="theory.html#interval/4">interval/4</A>
<A class="pred" href="theory.html#interval/2">interval/2</A>
<A class="pred" href="theory.html#interval/3">interval/3</A>
<A class="pred" href="theory.html#intervalSize/2">intervalSize/2</A>
<A class="pred" href="theory.html#chordChromaClasses/4">chordChromaClasses/4</A>
<A class="pred" href="theory.html#chordChromaSet/4">chordChromaSet/4</A>
<A class="pred" href="theory.html#chordNoteNums/2">chordNoteNums/2</A>
<A class="pred" href="theory.html#ranges/1">ranges/1</A>
<A class="pred" href="theory.html#selectVoicing/1">selectVoicing/1</A>
</BLOCKQUOTE>

<P><SPAN class="pred-ext">scalesOverChord/2</SPAN> (currently disabled 
because the caching takes several minutes. call private theory:<SPAN class="pred-ext">slowScalesOverChord/2</SPAN> 
with same spec. in release will be cached using <SPAN class="pred-ext">qsave_program/2</SPAN>).

<P><B>predicates related to chromas, notes, and intervals</B>
<BLOCKQUOTE>
<A class="pred" href="theory.html#raiseNumHalfSteps/3">raiseNumHalfSteps/3</A>
<A class="pred" href="theory.html#notes_chromas_nums/3">notes_chromas_nums/3</A>
<A class="pred" href="theory.html#all_enharmonics/2">all_enharmonics/2</A>
<A class="pred" href="theory.html#enharmonic/2">enharmonic/2</A>
<A class="pred" href="theory.html#enharmonicLists/2">enharmonicLists/2</A>
<A class="pred" href="theory.html#intervals/3">intervals/3</A>
<A class="pred" href="theory.html#intervals/2">intervals/2</A>
<A class="pred" href="theory.html#intervalSort/2">intervalSort/2</A>
<A class="pred" href="theory.html#intervalInversion/2">intervalInversion/2</A>
<SPAN class="pred-ext">allSpellingsOfNoteNum/2</SPAN>
<SPAN class="pred-ext">allNoteNums/1</SPAN>
<SPAN class="pred-ext">allNoteSpellings/1</SPAN>
<SPAN class="pred-ext">allSpellingsOfNote/2</SPAN>
<SPAN class="pred-ext">allSpellingsOfChroma/2</SPAN>
<SPAN class="pred-ext">allChromaSpellings/1</SPAN>
</BLOCKQUOTE>

<P><B>predicates related to scales, modes, keys, and degrees</B>
<BLOCKQUOTE>
<A class="pred" href="theory.html#scale/1">scale/1</A>
<A class="pred" href="theory.html#scale/3">scale/3</A>
<A class="pred" href="theory.html#mode/1">mode/1</A>
<A class="pred" href="theory.html#mode/2">mode/2</A>
<A class="pred" href="theory.html#mode/3">mode/3</A>
<A class="pred" href="theory.html#degree/3">degree/3</A>
<A class="pred" href="theory.html#key/1">key/1</A>
<SPAN class="pred-ext">properScale/1</SPAN>
<SPAN class="pred-ext">primeScale/1</SPAN>
</BLOCKQUOTE>

<P><B>predicates related to chords, voices, and voice leading</B>
<BLOCKQUOTE>
<A class="pred" href="theory.html#chord/4">chord/4</A>
<A class="pred" href="theory.html#numVoices/1">numVoices/1</A>
<A class="pred" href="theory.html#inRange/1">inRange/1</A>
<A class="pred" href="theory.html#consonantOver/2">consonantOver/2</A>
<A class="pred" href="theory.html#voiceLeadingOK/1">voiceLeadingOK/1</A>
</BLOCKQUOTE>

<P><B>predicates for functional interpretation of chords in keys</B>
<BLOCKQUOTE>
<A class="pred" href="theory.html#function/1">function/1</A>
<A class="pred" href="theory.html#function_roman/2">function_roman/2</A>
<A class="pred" href="theory.html#function/2">function/2</A>
<A class="pred" href="theory.html#simplifyFunction/2">simplifyFunction/2</A>
</BLOCKQUOTE>

<P><B>utility predicates of general interest</B>
<BLOCKQUOTE>
<SPAN class="pred-ext">shiftList/3</SPAN>
<A class="pred" href="theory.html#cumsum/2">cumsum/2</A>
<SPAN class="pred-ext">diff/2</SPAN>
<SPAN class="pred-ext">duplicate/3</SPAN>
<SPAN class="pred-ext">uniqueCombinations/3</SPAN>
<SPAN class="pred-ext">between/2</SPAN>
<SPAN class="pred-ext">reduce/2</SPAN>
<SPAN class="pred-ext">rand_insert/3</SPAN>
<SPAN class="pred-ext">insert/4</SPAN>
<SPAN class="pred-ext">fast_is_set/1</SPAN>
<SPAN class="pred-ext">romanNumeral/2</SPAN>
<A class="pred" href="theory.html#conforms/2">conforms/2</A>
<A class="pred" href="theory.html#generate/3">generate/3</A>
</BLOCKQUOTE>

<H4><A NAME="sec:1.2"><SPAN class="sec-nr">1.2</SPAN> <SPAN class="sec-title">conventions</SPAN></A></H4>

<P>in prolog, arguments are described with the following:
<BLOCKQUOTE>
<TABLE BORDER=2 FRAME=box RULES=groups>
<TR VALIGN=top><TD>+</TD><TD>must be fully instantiated to a term that 
satisfies the required argument type (think of the argument as input) </TD></TR>
<TR VALIGN=top><TD>-</TD><TD>must be unbound (think of the argument as 
output) </TD></TR>
<TR VALIGN=top><TD>?</TD><TD>can be either input or output </TD></TR>
</TABLE>

</BLOCKQUOTE>

<P>predicates have the following determinism indicators:
<BLOCKQUOTE>
<TABLE BORDER=2 FRAME=box RULES=groups>
<TR VALIGN=top><TD>det</TD><TD>will succeed exactly once (assuming you 
haven't grounded arguments inconsistently and have instantiated requied 
arguments) and not leave any choice-points (typical: arithmetic) </TD></TR>
<TR VALIGN=top><TD>semidet</TD><TD>will either fail or succeed 
deterministically -- won't leave any choice-points (typical: tests) </TD></TR>
<TR VALIGN=top><TD>nondet</TD><TD>no constraints on the number of times 
the predicate succeeds and whether or not it leaves choice-points 
(typical: generators) </TD></TR>
<TR VALIGN=top><TD>multi</TD><TD>as nondet, but the predicate will 
succeed at least once (assuming you haven't grounded arguments 
inconsistently and have instantiated requied arguments) </TD></TR>
</TABLE>

</BLOCKQUOTE>

<H4><A NAME="sec:1.3"><SPAN class="sec-nr">1.3</SPAN> <SPAN class="sec-title">viewing 
docmentaiton</SPAN></A></H4>

<P>these module docs can be auto-generated and viewed using the pldoc 
beta included in swipl via:

<PRE class="code">
doc_server(A),['theory.pl'],doc_browser.
</PRE>

<P>or they can be output to static html files using swipl's <A class="url" href="http://prolog.cs.vu.nl/git/pl-57x.git?a=tree;f=packages/ltx2htm;hb=HEAD">ltx2htm</A> 
- the git snapshot can be installed via:

<PRE class="code">
autoconf
autoheader
./configure
make
sudo make install
</PRE>

<P>then <CODE>cd</CODE> to the latex2html directory and do:

<PRE class="code">
ln -s pl.pl pldoc.pl
ln -s pl.cmd pldoc.cmd
</PRE>

<P>then, in swipl, do (extension MUST be .tex):

<PRE class="code">
doc_latex('theory.pl', 'theory.tex', public_only(false)).
</PRE>

<P>and finally, in a unix terminal:

<PRE class="code">
latex2html theory.tex
</PRE>

<H4><A NAME="sec:1.4"><SPAN class="sec-nr">1.4</SPAN> <SPAN class="sec-title">installation</SPAN></A></H4>

<P><B><A class="url" href="http://www.swi-prolog.org/">swipl</A> 
xplatform open source prolog</B>

<P>
<UL>
<LI>to install from source on osx (if for some reason you are unhappy 
with the binary installer -- <CODE>theory.pl</CODE> only needs 5.7 to 
generate docs):

<P>
<UL>
<LI>install <A class="url" href="http://www.macports.org/">macports</A>
<LI>install <A class="url" href="http://git-scm.com/">git</A> 1.6 or 
better (either via binary installer or via macports: <CODE>port install git</CODE>)
<LI><CODE>sudo port install swi-prolog</CODE> (installs swipl and 
dependencies to /opt/local/) -- if you already have an /opt/local/ from 
running the swipl binary installer, use <CODE>sudo port -f install swi-prolog</CODE> 
(see <CODE>man port</CODE>, may need to update $MANPATH to include 
/opt/local/share/man:/opt/local/man:/usr/share/man:/usr/local/share/man)
<LI><CODE>cd</CODE> to the directory where you want to clone swipl's git 
repository
<LI><CODE>git clone git://www.swi-prolog.org/home/pl/git/pl-57x.git</CODE> 
grabs the latest rev of swipl (check for name of <A class="url" href="http://www.swi-prolog.org/git/">dev 
branch</A> -- note that you canNOT build from a snapshot taken via this 
web interface)
<LI><CODE>cd</CODE> to the repository
<LI><CODE>./prepare</CODE>
<LI><CODE>cp build.templ build</CODE>
<LI>edit build:

<P>
<UL>
<LI>uncomment lines mentioned for osx
<LI>if you used macports above, you probably want to change 
PREFIX=/opt/local and delete the older swipl directories in 
/opt/local/bin/ (otherwise installs to $HOME and can't find <SPAN class="pred-ext">atomic_list_concat/2</SPAN>, 
which was called <SPAN class="pred-ext">concat_atom/2</SPAN> until 
5.7.8)
<LI>change other things mentioned as [EDIT] as you like (note ltxhtm 
cannot be installed using the PKG macro)
<LI>it survives without junit even if you don't tell it not to install 
jpl
</UL>

<P>
<LI><CODE>sudo ./build</CODE>
<LI>to pick up future updates, <CODE>cd</CODE> to the repository, and:

<PRE class="code">
make distclean
git pull
./prepare
./build
</PRE>

<P>
</UL>

<P>
<LI><A class="url" href="http://www.cs.kuleuven.be/~anton/xcode_prolog.html">prolog 
syntax coloring for xcode</A>
<LI><A class="url" href="http://cs.union.edu/~striegnk/learn-prolog-now/lpnpage.php?pageid=online">learn 
prolog now</A> excellent tutorial -- where i learned! only takes a 
couple hours and changes your life.
</UL>

<P><B><A class="url" href="http://code.google.com/p/pyswip/">pyswip</A> 
(bidirectional python interface to swipl)</B>

<P>
<UL>
<LI>on osx, python must be started like the following, or else it cannot 
find swipl's shared library:

<PRE class="code">
env DYLD_INSERT_LIBRARIES="/opt/local/lib/swipl-5.7.4/lib/i386-darwin9.6.0/libpl.dylib" python
</PRE>

<P>
<UL>
<LI>i used to use <CODE>DYLD_LIBRARY_PATH</CODE> but then the dynamic 
linker will still fail on code that uses certain swipl libraries (<CODE>random.pl</CODE>)
<LI><A class="url" href="http://trac.macports.org/wiki/FAQ\#WhyisoptlocalthedefaultinstalllocationforMacPorts">macports 
installs swipl to /opt/local/</A>, which is not on the standard search 
path for python's CDLL(), which calls the underlying platform's 
dlopen(), which searces paths specified by LD_LIBRARY_PATH and 
DYLD_LIBRARY_PATH

<P>
<UL>
<LI>it is not recommended to permanently set these envrionment variables 
(eg in .bash_profile or .cshrc) because they can be security exploits 
(search google for refs)
</UL>
</UL>
</UL>

<P><B><A class="url" href="http://alumni.media.mit.edu/~harrison/code.html">pyPortMidi</A> 
(python bindings for <A class="url" href="http://portmedia.sourceforge.net/">portmidi</A> 
-- xplatform realtime midi i/o -- via <A class="url" href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/">pyrex</A>)</B>

<P>
<UL>
<LI>the following is how i follow <A class="url" href="http://cratel.wichita.edu/cratel/cratel_pyportmidi">pyPortMidi's 
installation instructions</A>:

<P>
<UL>
<LI>according to portmidi readme, in portmidi directory, i did:

<PRE class="code">
make -f pm_mac/Makefile.osx
</PRE>

<P>
<UL>
<LI>note pyPortMidi's readme says to use <CODE>xcodebuild -project pm_mac.pbproj</CODE> 
from inside pm_mac directory -- i didn't do this
</UL>

<P>
<LI>according to pyrex <CODE>INSTALL.txt</CODE>, in pyrex directory, i 
did:

<PRE class="code">
python setup.py install
</PRE>

<P>
<UL>
<LI>i did not edit Pyrex/Mac/DarwinSystem.py. the os.environ line was at 
a much higher line number than 21 in this version. it read: <CODE>os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.3"</CODE>
</UL>

<P>
<LI>copy the following:

<P><UL COMPACT>
<LI>portmidi/porttime/porttime.h <CODE>-&gt;</CODE> pyPortMidi
<LI>portmidi/pm_common/portmidi.h <CODE>-&gt;</CODE> pyPortMidi
<LI>portmidi/pm_mac/libportmidi.a <CODE>-&gt;</CODE> pyPortMidi/OSX
<LI>portmidi/porttime/libporttime.a <CODE>-&gt;</CODE> pyPotMidi/OSX
</UL>

<P>
<LI>changed line in pypm.pyx to <CODE>while(Pm_Poll(self.midi) != pmNoError):</CODE>
<LI>changed line in pyPortMidi's setup.py to <CODE>libraries = ["portmidi", "porttime"],</CODE>
<LI>in pyPortMidi directory: <CODE>sudo python setup.py install</CODE>
<LI>in pyPortMidi directory, use <CODE>python test.py</CODE> to test 
that midi i/o is working.

<P>
<UL>
<LI>to use a software synth on osx:

<P>
<UL>
<LI>open Audio MIDI Setup (in /Applications/Utilities)
<LI>under MIDI devices, double click IAC Driver
<LI>check "Device is online"
<LI>expand for "More Information" and make sure there is a port with in 
and out connectors
</UL>

<P>
<LI>you can also drive a midi interface to external hardware synths via 
this panel, or mingus now has <A class="url" href="http://www.nongnu.org/fluid/">fluidsynth</A> 
built in.
<LI>i use <A class="url" href="http://www.apple.com/logicstudio/">logic 
pro</A>, but free options are <A class="url" href="http://www.fredrikolofsson.com/software/vmk16osx.sit">vmk</A> 
(a soft keyboard for midi input) and <A class="url" href="http://notahat.com/downloads/SimpleSynth-1.0.zip">simplesynth</A> 
(a soft synth for midi output)
</UL>
</UL>
</UL>

<P><B><A class="url" href="http://lilypond.org/web/">lilypond</A> high 
quality music notation.</B>

<P><UL COMPACT>
<LI>i installed with <CODE>port install lilypond</CODE>
</UL>

<P><B><A class="url" href="http://www.pythonware.com/products/pil/">python 
imaging library (PIL)</A></B>

<P>
<UL>
<LI>used by python to show notation .png's generated in lilypond.
<LI>i installed with <CODE>port install py26-pil</CODE>
<LI>i had to add the following to .bash_profile because i had manually 
installed python2.6 before installing macports:

<PRE class="code">
export PYTHONPATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/
</PRE>

<P>
</UL>

<H4><A NAME="sec:1.5"><SPAN class="sec-nr">1.5</SPAN> <SPAN class="sec-title">general 
info</SPAN></A></H4>

<DL>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="numNotesPerOctave/1"><STRONG>numNotesPerOctave</STRONG>(<VAR>?N:integer</VAR>)</A></DT>
<DD class="defbody">
number of half steps per octave.

<P>hardcoded to <CODE>12</CODE>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>N</VAR> </TD><TD>number of half steps per octave </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="whiteKeys/1"><STRONG>whiteKeys</STRONG>(<VAR>?L:pairs(key-value)</VAR>)</A></DT>
<DD class="defbody">
white key locations and names.

<P>hardcoded to <CODE>[0-a,2-b,3-c,5-d,7-e,8-f,10-g]</CODE>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>L</VAR> </TD><TD>key-value pairs where keys are 
unique integers <CODE>&gt;=</CODE>0 representing half step intervals 
above the lowest and values are atoms representing note names (order 
unimportant) </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="accidentals/1"><STRONG>accidentals</STRONG>(<VAR>?L:list</VAR>)</A></DT>
<DD class="defbody">
accidental definition.

<P>hardcoded to <CODE>[bb,b,'',#,x]</CODE>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>L</VAR> </TD><TD>list of unique atoms 
representing accidentals in order from lowest to highest, must be 
separated by exact halfsteps, must contain the empty string (''), which 
corresponds to natural (no accidental) </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="intervalNamesTypes/1"><STRONG>intervalNamesTypes</STRONG>(<VAR>?L:list([degree, 
type])</VAR>)</A></DT>
<DD class="defbody">
interval degrees and types.

<P>hardcoded to <CODE>[[octave,perfect],[second,imperfect],[third,imperfect],[fourth,perfect],[fifth,perfect],[sixth,imperfect],[seventh,imperfect]]</CODE>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>L</VAR> </TD><TD>list of length-2 lists, where 
each sublist is [degree,type], in order from lowest to highest, must be 
same length as whiteKeys, degrees must be unique and contain one <CODE>fifth</CODE>, 
types in <CODE>[perfect, imperfect]</CODE> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="intervalQualities/2"><STRONG>intervalQualities</STRONG>(<VAR>?Type, 
?Qualities:list</VAR>)</A></DT>
<DD class="defbody">
interval types and qualities.

<P>hardcoded so perfect<CODE>-&gt;</CODE><CODE>[diminished,perfect,augmented]</CODE> 
and imperfect<CODE>-&gt;</CODE><CODE>[diminished,minor,major,augmented]</CODE>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Type</VAR> </TD><TD>interval type atom in <CODE>[perfect, imperfect]</CODE> </TD></TR>
<TR VALIGN=top><TD><VAR>Qualities</VAR> </TD><TD>list of unique 
qualities corresponding to <VAR>Type</VAR>, in order from lowest to 
highest, separated by exact halfsteps (perfect must contain perfect, and 
imperfect must contain major, which both correspond to natural) </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chordQuality/2"><STRONG>chordQuality</STRONG>(<VAR>?Intervals:list([quality, 
degree]), ?Quality</VAR>)</A></DT>
<DD class="defbody">
chord qualities and intervals

<P>hardcoded intervalic content of triads and seventh chords.

<P>ex:

<PRE class="code">
chordQuality([[minor,third],[diminished,fifth],[minor,seventh]],halfdiminished).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Intervals</VAR> </TD><TD>list of length-2 lists, 
where each sublist is [quality,degree], sorted by interval size, all 
unique, none can be [perfect,octave] </TD></TR>
<TR VALIGN=top><TD><VAR>Quality</VAR> </TD><TD>corresponding chord 
quality </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chordQuality/3"><STRONG>chordQuality</STRONG>(<VAR>?Intervals:list([quality, 
degree]), ?Quality, ?Size</VAR>)</A></DT>
<DD class="defbody">
chord qualities, intervals, and sizes

<P>hardcoded sizes of triads and seventh chords.

<P>ex:

<PRE class="code">
chordQuality([[minor,third],[diminished,fifth],[minor,seventh]],halfdiminished,seven).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Intervals</VAR> </TD><TD>list of length-2 lists, 
where each sublist is [quality,degree], sorted by interval size, all 
unique, none can be [perfect,octave] </TD></TR>
<TR VALIGN=top><TD><VAR>Quality</VAR> </TD><TD>corresponding chord 
quality </TD></TR>
<TR VALIGN=top><TD><VAR>Size</VAR> </TD><TD>corresponding chord size in <CODE>[triad,seven]</CODE> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chordInversion/2"><STRONG>chordInversion</STRONG>(<VAR>?Inversion, 
?BassDegree</VAR>)</A></DT>
<DD class="defbody">
chord inversion definitions

<P>hardcodes names of inversions, for each degree of the bass over the 
root.

<P>ex:

<PRE class="code">
chordInversion(root,octave).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Inversion</VAR> </TD><TD>name of the inversion 
in <CODE>[root,first,second,third]</CODE> </TD></TR>
<TR VALIGN=top><TD><VAR>BassDegree</VAR> </TD><TD>degree of the bass 
over the root </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="scaleName/2"><STRONG>scaleName</STRONG>(<VAR>?Intervals:list(integers), 
?Name</VAR>)</A></DT>
<DD class="defbody">
common scale definitions

<P>definition of chromatic, diatonic, major, minor, harmonicMinor, and 
melodicMinor scales in terms of their intervalic content.

<P>ex:

<PRE class="code">
scaleName([2,2,1,2,2,2,1],major).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Intervals</VAR> </TD><TD>list of <VAR>&gt;</VAR>0 
integers representing half steps between successive scale degrees, must 
sum to numNotesPerOctave </TD></TR>
<TR VALIGN=top><TD><VAR>Quality</VAR> </TD><TD>corresponding chord 
quality </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="modeName/3"><STRONG>modeName</STRONG>(<VAR>?Num:integer, 
?Scale, ?ModeName</VAR>)</A></DT>
<DD class="defbody">
common mode definitions

<P>definition of the familiar diatonic church modes, plus the jazz modes 
of melodic and harmonic minor.

<P>ex:

<PRE class="code">
modeName(1,[2, 2, 1, 2, 2, 2, 1],ionian).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Num</VAR> </TD><TD>integer from 1 to 
numNotesPerOctave indicating the mode </TD></TR>
<TR VALIGN=top><TD><VAR>Scale</VAR> </TD><TD>list of <VAR>&gt;</VAR>0 
integers representing half steps between successive scale degrees of the 
underlying scale, must sum to numNotesPerOctave </TD></TR>
<TR VALIGN=top><TD><VAR>ModeName</VAR> </TD><TD>the mode name </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="octaveBreaks/1"><STRONG>octaveBreaks</STRONG>(<VAR>?W:whiteKey</VAR>)</A></DT>
<DD class="defbody">
indicates the lowest white key of each octave number

<P>note the possible ambiguity of octave numbers for enharmonic notes. 
we use the following convention:

<P>[bb0, a#0, cbb1], [b0, ax0, cb1], [c1, b#0, dbb1], [c#1, bx0, db1], 
d1, ..., b1, c2, d2, ...

<P>hardcoded to <CODE>c</CODE>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>W</VAR> </TD><TD>the lowest whiteKey in each 
octave </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="voice/3"><STRONG>voice</STRONG>(<VAR>?Name, 
?Low:note, ?High:note</VAR>)</A></DT>
<DD class="defbody">
voice definitions and ranges

<P>hardcoded definition of voices and their ranges. taken from 
roig-francoli, which is at slight variance from aldwell and schachter. 
these are what limit the domain of notes so that all predicates are fast 
and finite, even with no arguments instantated.

<P>notes are <CODE>[Chroma,Octave:integer]</CODE> (octave <CODE>&gt;=</CODE> 
1 -- i forget why, may no longer be required?)

<P>chromas are <CODE>[WhiteKeyName,Accidental]</CODE>

<P>names are in <CODE>[bass,tenor,alto,soprano]</CODE>

<P>ex:

<PRE class="code">
voice(bass,[[e,''],1],[[g,''],2]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Name</VAR> </TD><TD>name of voice </TD></TR>
<TR VALIGN=top><TD><VAR>Low</VAR> </TD><TD>low extent </TD></TR>
<TR VALIGN=top><TD><VAR>High</VAR> </TD><TD>high extent </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="refNoteNum/2"><STRONG>refNoteNum</STRONG>(<VAR>?Note:note, 
?MidiNum:integer</VAR>)</A></DT>
<DD class="defbody">
definition of relationship between notes and midi note numbers. 
establishes middle c = <CODE>[[c,''],3]</CODE>.

<P>hardcoded as <CODE>refNoteNum([[c,''],3],60).</CODE>

<P>notes are <CODE>[Chroma,Octave:integer]</CODE> (octave <CODE>&gt;=</CODE> 
1 -- i forget why, may no longer be required?)

<P>chromas are <CODE>[WhiteKeyName,Accidental]</CODE>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Note</VAR> </TD><TD>the reference note </TD></TR>
<TR VALIGN=top><TD><VAR>MidiNum</VAR> </TD><TD>the corresponding midi 
note number </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="consonant/1"><STRONG>consonant</STRONG>(<VAR>?Interval</VAR>)</A></DT>
<DD class="defbody">
definition of consonant intervals

<P>hardcoded so quality must be in <CODE>[perfect,major,minor]</CODE> 
(notice these are closed under inversion) and degree must be in <CODE>[octave,third,fourth,fifth,sixth]</CODE>

<P>this isn't a subjective call, it is determined by how many overtone 
harmonics are shared between tones, and is an axiom of common practice 
harmony. chords may not double any dissonance over the root or bass. 
dissonances (non-consonances) must resolve by step on their next 
movement (or exchange with a voice that does). theory: this is enough 
asymmetric motive force to drive progressive movement with no functional 
interpretation/restrictions, allowing maximum freedom in tonality 
("borrowed" and "passing" chords, "modulation" and "tonicization", may 
all be ad hoc patches on an overly-dogmatic theory of tonal function 
focused on repose at a single tonic). i would like to contrast a concern 
for local resolution with schenker's focus on global key centers).

<P>ex:

<PRE class="code">
consonant([major,third]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Interval</VAR> </TD><TD>the interval as 
2-element list [quality,degree] </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="functions/1"><STRONG>functions</STRONG>(<VAR>?F:list</VAR>)</A></DT>
<DD class="defbody">
definitions for functions served by chords with roots relative to a 
tonic.

<P>hardcoded to <CODE>[tonic,supertonic,mediant,subdominant,dominant,submediant,leadingTone]</CODE>

<P>need to change to be <CODE>[tonic,'b supertonic',supertonic,'b mediant',mediant,subdominant,'b dominant',dominant,'b submediant',submediant,subtonic,leadingTone]</CODE>, 
which will require changing the function interpretation predicates
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>F</VAR> </TD><TD>the ordered list of function 
names -- currently the same length as whiteKeys, but after fix, will be 
same length as octave </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="raiseNumHalfSteps/3"><STRONG>raiseNumHalfSteps</STRONG>(<VAR>?Note1, 
?Note2, ?NumHalfSteps</VAR>)</A></DT>
<DD class="defbody">
find number of half steps between two notes

<P>notice the octave breaks convention in <A class="pred" href="theory.html#octaveBreaks/1">octaveBreaks/1</A>

<P>ex:

<PRE class="code">
raiseNumHalfSteps([[g, x], 2],[[c,''],4],15).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Note1</VAR> </TD><TD>Note in format 
[[Chroma],OctaveNumber] ala <A class="pred" href="theory.html#note/1">note/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Note2</VAR> </TD><TD>Note in format 
[[Chroma],OctaveNumber] ala <A class="pred" href="theory.html#note/1">note/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>NumHalfSteps</VAR> </TD><TD><VAR>NumHalfSteps</VAR> 
from <VAR>Note1</VAR> up to <VAR>Note2</VAR> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="notes_chromas_nums/3"><STRONG>notes_chromas_nums</STRONG>(<VAR>?Notes, 
?Chromas, ?Nums</VAR>)</A></DT>
<DD class="defbody">
finds the <VAR>Chromas</VAR> and MIDI note numbers of a list of <VAR>Notes</VAR>

<P><VAR>Notes</VAR>, <VAR>Chromas</VAR>, and <VAR>Nums</VAR> are all 
lists that are the same length, and contain information about 
corresponding <VAR>Notes</VAR>

<P>ex:

<PRE class="code">
notes_chromas_nums([[[e, b], 3],[[e, b], 4],[[e, b], 5],[[e, ''], 1]], [[e, b], [e, b], [e, b], [e, '']],[63,75,87,40]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Notes</VAR> </TD><TD>list of <VAR>Notes</VAR> in 
format [[Chroma],OctaveNumber] ala <A class="pred" href="theory.html#note/1">note/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Chromas</VAR> </TD><TD>list of <VAR>Chromas</VAR> 
in format [WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Nums</VAR> </TD><TD>list of corresponding MIDI 
note numbers </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="all_enharmonics/2"><STRONG>all_enharmonics</STRONG>(<VAR>+Chromas, 
-EnharmonicChromas</VAR>)</A></DT>
<DD class="defbody">
finds all chromas enharmonic to <VAR>Chromas</VAR> in a list

<P>ex:

<PRE class="code">
all_enharmonics([[c,'']],[[b, #], [c, ''], [d, bb]].).
all_enharmonics([[c,''],[e,'']],[[b, #], [c, ''], [d, bb], [d, x], [e, ''], [f, b]]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chromas</VAR> </TD><TD>list of <VAR>Chromas</VAR> 
in format [WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>EnharmonicChromas</VAR> </TD><TD>sorted list of 
all <VAR>Chromas</VAR> in format [WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> 
enharmonic to at least one member of <VAR>Chromas</VAR> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="enharmonic/2"><STRONG>enharmonic</STRONG>(<VAR>?Chroma1, 
?Chroma2</VAR>)</A></DT>
<DD class="defbody">
determine if two Chroma are enharmonic (members of the same pitch class)

<P>ex:

<PRE class="code">
enharmonic([b,x],[c, #]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chroma1</VAR> </TD><TD>Chroma in format 
[WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> 
(if only one argument is ground, faster to instantiate this one) </TD></TR>
<TR VALIGN=top><TD><VAR>Chroma2</VAR> </TD><TD>Chroma in format 
[WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[semidet]</span><A NAME="enharmonicLists/2"><STRONG>enharmonicLists</STRONG>(<VAR>+ChromaList1, 
+ChromaList2</VAR>)</A></DT>
<DD class="defbody">
determine if two Chroma lists contain any Chroma not enharmonic to the 
other

<P>ex:

<PRE class="code">
enharmonicLists([[b,x],[e,''],[f,x]],[[g,''],[e,''],[c, #],[d,b],[f,b]]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>ChromaList1</VAR> </TD><TD>list of Chroma in 
format [WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>ChromaList2</VAR> </TD><TD>list of Chroma in 
format [WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="intervals/3"><STRONG>intervals</STRONG>(<VAR>?Root, 
?ChromaList, ?IntervalList</VAR>)</A></DT>
<DD class="defbody">
find all intervals of a list of chromas over a root

<P>at least one of <VAR>ChromaList</VAR> or <VAR>IntervalList</VAR> has 
to be ground, or else we get stuck making infinite lists. could be 
fixed.

<P>ex:

<PRE class="code">
intervals([c,''],[[b,x],[e,''],[g,b]],L). % fails - there is no interval from [c,''] up to [b,x] -- a double augmented seventh
intervals([c,''],[[b,#],[e,''],[g,b]],[[augmented, seventh], [major, third], [diminished, fifth]]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Root</VAR> </TD><TD>list of Chroma in format 
[WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>ChromaList</VAR> </TD><TD>list of Chroma in 
format [WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>IntervalList</VAR> </TD><TD>list of Intervals in 
format [Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="intervals/2"><STRONG>intervals</STRONG>(<VAR>+ChromaList, 
-IntervalList</VAR>)</A></DT>
<DD class="defbody">
find all ascending intervals moving from left to right in a chroma list

<P>note non-existant intervals like double-augmented-fifths (eg c to gx) 
are omitted.

<P>ex:

<PRE class="code">
intervals([[c,''],[e,''],[g,x],[a,b]],[1-2-[major, third], 1-4-[minor, sixth], 2-3-[augmented, third], 2-4-[diminished, fourth]]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>ChromaList</VAR> </TD><TD>list of Chroma in 
format [WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>IntervalList</VAR> </TD><TD>list of Intervals in 
format N-M-[Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A>, 
where N and M are the 1-based indices of the corresponding Chroma in <VAR>ChromaList</VAR> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="intervalSort/2"><STRONG>intervalSort</STRONG>(<VAR>+IntervalList, 
?Sorted</VAR>)</A></DT>
<DD class="defbody">
sort intervals according to their size in half steps, and then by degree 
distance

<P>sorted according to the 2-tuple second arg of <VAR>IntervalList</VAR>/2

<P>ex:

<PRE class="code">
intervalSort([[minor,third],[major,second],[augmented,second]],[[major, second], [augmented, second], [minor, third]]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>IntervalList</VAR> </TD><TD>list of Intervals in 
format [Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Sorted</VAR> </TD><TD>list of Intervals in 
format [Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> 
sorted according to their size in half steps, and then by degree 
distance </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="intervalInversion/2"><STRONG>intervalInversion</STRONG>(<VAR>?Interval, 
?Inverted</VAR>)</A></DT>
<DD class="defbody">
find inteval inversions

<P>ex:

<PRE class="code">
intervalInversion([diminished, third],[augmented, sixth]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Interval</VAR> </TD><TD><VAR>Interval</VAR> in 
format [Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Inverted</VAR> </TD><TD>Inversion of <VAR>Interval</VAR> 
in format <VAR>Interval</VAR> in format [Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="scale/1"><STRONG>scale</STRONG>(<VAR>?L</VAR>)</A></DT>
<DD class="defbody">
find all possible scales

<P>the most general possible definition of a scale is a sequence of 
strictly positive intervals whose halfstep sizes add up to the total 
number of halfsteps per octave. that is it must be strictly monotonic 
without enharmonics or overlaps (if have [d,b], cannot have either [c,#] 
or [c,x]).

<P>ex:

<PRE class="code">
scale([1, 1, 1, 1, 1, 1, 6]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>L</VAR> </TD><TD>a sequence of integers <CODE>&gt;=</CODE>1 
that add up to N, where N is numNotesPerOctave(N) </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="scale/3"><STRONG>scale</STRONG>(<VAR>?Root, 
?Scale, ?Chromas</VAR>)</A></DT>
<DD class="defbody">
find <VAR>Chromas</VAR> of a <VAR>Scale</VAR> over a <VAR>Root</VAR> 
Chroma

<P>the Chroma names are only determined for scales of the same length as <A class="pred" href="theory.html#whiteKeys/1">whiteKeys/1</A>, 
so we fail otherwise.

<P>note that not all sequences of 7 positive integers that add to 12 can 
be a scale over every <VAR>Root</VAR> Chroma -- there is no gx major 
scale because there is no Chroma fx#

<P>ex:

<PRE class="code">
scale([e,b],[1, 1, 2, 4, 1, 1, 2],[[e, b], [f, b], [g, bb], [a, bb], [b, ''], [c, ''], [d, b]]).
scale([g,x],[2,2,1,2,2,2,1],C). % fails -- no such chroma as fx#
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Root</VAR> </TD><TD>a Chroma of the form 
[WhiteKey,Accidental] ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Scale</VAR> </TD><TD>a sequence of integers <CODE>&gt;=</CODE>1 
that add up to N, where N is numNotesPerOctave(N), ala <A class="pred" href="theory.html#scale/1">scale/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Chromas</VAR> </TD><TD>the corresponding 
sequence of <VAR>Chromas</VAR> with the specified intervals over <VAR>Root</VAR> 
(each white key, inflected by some accidental, will be represented 
exactly once) </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="mode/1"><STRONG>mode</STRONG>(<VAR>?Name</VAR>)</A></DT>
<DD class="defbody">
find mode names

<P>ex:

<PRE class="code">
mode(phrygian).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Name</VAR> </TD><TD>any of the mode names 
defined by the third argument of <A class="pred" href="theory.html#modeName/3">modeName/3</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="mode/2"><STRONG>mode</STRONG>(<VAR>?Name, 
?Scale</VAR>)</A></DT>
<DD class="defbody">
find mode names and their scales

<P>ex:

<PRE class="code">
mode(phrygian,[1, 2, 2, 2, 1, 2, 2]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Name</VAR> </TD><TD>any of the mode names 
defined by the third argument of <A class="pred" href="theory.html#modeName/3">modeName/3</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Scale</VAR> </TD><TD>the corresponding <VAR>Scale</VAR> 
ala <A class="pred" href="theory.html#scale/1">scale/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="mode/3"><STRONG>mode</STRONG>(<VAR>?Root, 
?Name, ?Chromas</VAR>)</A></DT>
<DD class="defbody">
find <VAR>Chromas</VAR> for Named modes starting on <VAR>Root</VAR>

<P>ex:

<PRE class="code">
mode([g,x],phrygian,[[g, x], [a, #], [b, #], [c, x], [d, x], [e, #], [f, x]]).
mode([g,x],major,L). % fails - no such chroma as fx#
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Root</VAR> </TD><TD>a Chroma ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Name</VAR> </TD><TD>any of the mode names 
defined by the third argument of <A class="pred" href="theory.html#modeName/3">modeName/3</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Chromas</VAR> </TD><TD>the corresponding <VAR>Chromas</VAR> 
ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="degree/3"><STRONG>degree</STRONG>(<VAR>?N, 
?Key, ?Chroma</VAR>)</A></DT>
<DD class="defbody">
find scale Degrees in Keys

<P>ex:

<PRE class="code">
degree(4,[[g,''],dorian],[c,'']).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>N</VAR> </TD><TD>the 1-based degree (1 is Root) 
-- can be any integer <CODE>&gt;=</CODE>1 (should fix to allow 
negatives) </TD></TR>
<TR VALIGN=top><TD><VAR>Key</VAR> </TD><TD><VAR>Key</VAR> in format [<VAR>Chroma</VAR>,Mode] 
ala <A class="pred" href="theory.html#key/1">key/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Chroma</VAR> </TD><TD>the <VAR>Chroma</VAR> at 
the specified Degree in the <VAR>Key</VAR>, ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="key/1"><STRONG>key</STRONG>(<VAR>?Key</VAR>)</A></DT>
<DD class="defbody">
keys specify a root Chroma in a Mode

<P>ex:

<PRE class="code">
key([[a, b], locrianRaise2]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Key</VAR> </TD><TD><VAR>Key</VAR> in format 
[Chroma,Mode], ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> 
and <A class="pred" href="theory.html#mode/1">mode/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chord/4"><STRONG>chord</STRONG>(<VAR>?Chromas, 
?Root, ?Quality, ?Size</VAR>)</A></DT>
<DD class="defbody">
chord recognition - find <VAR>Chromas</VAR> associated with a chord with <VAR>Root</VAR>, <VAR>Quality</VAR>, 
and <VAR>Size</VAR>

<P>there are 23,380 of these, but only 10,084 are unique cuz our 
generator method makes a few dupes (expect fewer when we eliminate R333, 
RR33, and R337)

<P>the <VAR>Chromas</VAR>-chord relationship is never ambiguous when the 
constraints in <A class="pred" href="theory.html#chordChromaClasses/4">chordChromaClasses/4</A> 
are followed

<PRE class="code">
chord(A,[f,#],halfdiminished,seven).

A = [[a, ''], [c, ''], [e, ''], [f, #]] ;
A = [[c, ''], [a, ''], [e, ''], [f, #]] ;
A = [[c, ''], [e, ''], [a, ''], [f, #]] ;
A = [[c, ''], [e, ''], [f, #], [a, '']] ;
A = [[a, ''], [e, ''], [c, ''], [f, #]] ;
A = [[e, ''], [a, ''], [c, ''], [f, #]] ;
A = [[e, ''], [c, ''], [a, ''], [f, #]] ;
A = [[e, ''], [c, ''], [f, #], [a, '']] ;
A = [[a, ''], [e, ''], [f, #], [c, '']] ;
A = [[e, ''], [a, ''], [f, #], [c, '']] ;
A = [[e, ''], [f, #], [a, ''], [c, '']] ;
A = [[e, ''], [f, #], [c, ''], [a, '']] ;
A = [[a, ''], [c, ''], [f, #], [e, '']] ;
A = [[c, ''], [a, ''], [f, #], [e, '']] ;
A = [[c, ''], [f, #], [a, ''], [e, '']] ;
A = [[c, ''], [f, #], [e, ''], [a, '']] ;
A = [[a, ''], [f, #], [c, ''], [e, '']] ;
A = [[f, #], [a, ''], [c, ''], [e, '']] ;
A = [[f, #], [c, ''], [a, ''], [e, '']] ;
A = [[f, #], [c, ''], [e, ''], [a, '']] ;
A = [[a, ''], [f, #], [e, ''], [c, '']] ;
A = [[f, #], [a, ''], [e, ''], [c, '']] ;
A = [[f, #], [e, ''], [a, ''], [c, '']] ;
A = [[f, #], [e, ''], [c, ''], [a, '']] ;
false.
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chromas</VAR> </TD><TD>any permutation of a list 
of chromas with length specified by <A class="pred" href="theory.html#numVoices/1">numVoices/1</A> 
that satisfies <A class="pred" href="theory.html#chordChromaClasses/4">chordChromaClasses/4</A> 
for this (<VAR>Chromas</VAR>, <VAR>Root</VAR>, <VAR>Quality</VAR>, <VAR>Size</VAR>) </TD></TR>
<TR VALIGN=top><TD><VAR>Root</VAR> </TD><TD>a chroma ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Quality</VAR> </TD><TD>chord quality ala second 
argument of <A class="pred" href="theory.html#chordQuality/3">chordQuality/3</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Size</VAR> </TD><TD>chord size ala third 
argument of <A class="pred" href="theory.html#chordQuality/3">chordQuality/3</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="numVoices/1"><STRONG>numVoices</STRONG>(<VAR>?N</VAR>)</A></DT>
<DD class="defbody">
find the number of voices defined by <A class="pred" href="theory.html#voice/3">voice/3</A>

<P>ex:

<PRE class="code">
numVoices(4).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>N</VAR> </TD><TD>the number of voices defined by <A class="pred" href="theory.html#voice/3">voice/3</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="inRange/1"><STRONG>inRange</STRONG>(<VAR>?NoteNums</VAR>)</A></DT>
<DD class="defbody">
find list of <VAR>NoteNums</VAR> in ranges specified by <A class="pred" href="theory.html#voice/3">voice/3</A>

<P><A class="pred" href="theory.html#inRange/1">inRange/1</A> enforces 
the voice location rules specified in <A class="pred" href="theory.html#selectVoicing/1">selectVoicing/1</A>

<P>
<UL>
<LI>one note for each voice defined by <A class="pred" href="theory.html#voice/3">voice/3</A>, 
in the specified range, without overlap (unison OK. aldwell schacter and 
roig-francoli both suggest that brief crossing can be acceptable in 
inner voices, we may relax this constraint.).
<LI>at most one octave between adjacent voices (2 octaves may separate 
the bottom 2 voices) ex:

<PRE class="code">
inRange([40, 48, 55, 61]).
</PRE>

<P>
</UL>
<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>NoteNums</VAR> </TD><TD>list of MIDI <VAR>NoteNums</VAR> 
in ranges specified by <A class="pred" href="theory.html#voice/3">voice/3</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="consonantOver/2"><STRONG>consonantOver</STRONG>(<VAR>?Chroma1, 
?Chroma2</VAR>)</A></DT>
<DD class="defbody">
find consonant Chroma relationships

<P>consonance defined by <A class="pred" href="theory.html#consonant/1">consonant/1</A> 
(note this is a symmetric relation - inversions of consonances are 
always consonant (may not hold outside of 12TET?))

<P>ex:

<PRE class="code">
consonantOver([c,''],[e,'']).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chroma1</VAR> </TD><TD>a chroma, ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Chroma2</VAR> </TD><TD>a chroma, ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="voiceLeadingOK/1"><STRONG>voiceLeadingOK</STRONG>(<VAR>?VoicingList</VAR>)</A></DT>
<DD class="defbody">
find sequences of Voicings that comply to voice leading rules

<P>each member of VoiceingList is a 2-list [NoteNumList,Voicing], where 
Voicing is as <A class="pred" href="theory.html#selectVoicing/1">selectVoicing/1</A>, 
and NoteNumList is the corresponding list of note numbers ala <A class="pred" href="theory.html#noteNum/2">noteNum/2</A>

<P>in addition to enforcing that each Voicing adhere to the Voicing 
rules in <A class="pred" href="theory.html#selectVoicing/1">selectVoicing/1</A>, <A class="pred" href="theory.html#voiceLeadingOK/1">voiceLeadingOK/1</A> 
enforces:

<P>
<UL>
<LI>no dissonant melodic intervals within a voice
<LI>at most one voice leaps more than a third on any transition
<LI>that the next movement in a voice after a leap greater than a third 
is stepwise in the opposite direction
<LI>at least one voice moves during each transition
<LI>no parallel or contrary perfect fifths or perfect octaves (incl 
unisons)
<LI>no direct/hidden perfect fifths or perfect octaves (landing on a 
perfect fifth via similar motion) between the outer voices unless the 
top voice moves by step
<LI>no consecutive fifths of any quality btw outer voices (unless 
neither moved)
<LI>no voice overlap (one voice crossing over an adjacent voice's 
previous position)
</UL>

<P>ex:

<PRE class="code">
length(L,4),voiceLeadingOK(L),maplist(writeln,L).
[[55, 64, 67, 67], [[[[a, bb], 2], [[f, b], 3], [[a, bb], 3], [[a, bb], 3]], [f, b], minor, triad, first]]
[[47, 55, 65, 74], [[[[c, b], 2], [[a, bb], 2], [[g, bb], 3], [[e, bb], 4]], [a, bb], dominant, seven, first]]
[[48, 57, 69, 72], [[[[d, bb], 2], [[b, bb], 2], [[b, bb], 3], [[d, bb], 4]], [b, bb], minor, triad, first]]
[[48, 60, 70, 76], [[[[d, bb], 2], [[d, bb], 3], [[c, bb], 4], [[f, b], 4]], [d, bb], dominant, seven, root]]
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>VoicingList</VAR> </TD><TD>each member of 
VoiceingList is a 2-list [NoteNumList,Voicing], where Voicing is as <A class="pred" href="theory.html#selectVoicing/1">selectVoicing/1</A>, 
and NoteNumList is the corresponding list of note numbers ala <A class="pred" href="theory.html#noteNum/2">noteNum/2</A> </TD></TR>
</TABLE>

<DL>
<DT><B>bug</B><DD> seems to allow multiple voices to leap more than a 
third on individual transitions, i think because <A class="pred" href="theory.html#intervals/2">intervals/2</A> 
omits non-existant intervals
<DT><B>To be done</B><DD>
<UL>
<LI>dissonance resolution rules
<LI>can't double dissonance over tonic (at least leading tone), and they 
have to resolve a certain way (leading tone to tonic unless voice above 
goes to that note - roig-francoli p.144 says LT jumping up a 4th 
sometimes ok!?!)
<UL>
<LI>but need to know functional interpretation of chord to know what is 
tonic, and i'm trying to be agnostic about that
<LI>put this in separate place using the key recommendation idea
</UL>
<LI>highest and lowest points in outer voices should occur once and at 
different times from each other
</UL>
</DL>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="function/1"><STRONG>function</STRONG>(<VAR>?QualifiedFunction</VAR>)</A></DT>
<DD class="defbody">
defines the successive application of functions on a key in a mode

<P><VAR>QualifiedFunction</VAR> is of the form [[RomanNumeralList],Key], 
where Key is of the form [Chroma,Mode]. the RomanNumerals represent 
functions that are sequentially applied to the tonic Key.

<P>for example, V of c major is g dominant. II of that V would be a 
minor.

<P>'I's are not used because they are tonic identities that would 
clutter our lists -- this should be reconsidered and would be alleviated 
by moving to bredth-first exploration.

<P>ex:

<PRE class="code">
function([['V'],        [[c,''],major]]). % V in c major is g dominant
function([['II','V'],   [[c,''],major]]). % II/V in c major is a minor

function([['I'],        [[c,''],major]]). % fails!  use the following instead:
function([[],           [[c,''],major]]). % tonic
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>QualifiedFunction</VAR> </TD><TD>a function in 
the form [[RomanNumeralList],Key], with Key of form [Chroma,Mode]. if 
RomanNumeralList is not ground, it is explored depth-first (an 
ever-extending list of 'II's), which should be changed to bredth-first. </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="function_roman/2"><STRONG>function_roman</STRONG>(<VAR>?Function, 
?RomanNumeral</VAR>)</A></DT>
<DD class="defbody">
associations between function names and roman numerals.

<P>need to change to use new <A class="pred" href="theory.html#functions/1">functions/1</A>, 
which will mean that the roman numeral may be modified with a flat sign.

<P>ex:

<PRE class="code">
function_roman(subdominant,'IV').
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Function</VAR> </TD><TD>the function name as 
defined by <A class="pred" href="theory.html#functions/1">functions/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>RomanNumeral</VAR> </TD><TD>a capitalized roman 
numeral corresponding to the position of <VAR>Function</VAR> in <A class="pred" href="theory.html#functions/1">functions/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="function/2"><STRONG>function</STRONG>(<VAR>?Chord, 
?QualifiedFunction</VAR>)</A></DT>
<DD class="defbody">
relation between specific chords and the function they serve in specific 
keys/modes

<P><VAR>Chord</VAR> is in the form [ChromaSet, Root, Quality, Size], as 
in <A class="pred" href="theory.html#chordChromaSet/4">chordChromaSet/4</A> 
(note that ChromaSet does not contain dupes and is ordered by degree!). <VAR>Chord</VAR> 
fills the <VAR>QualifiedFunction</VAR> specified.

<P>if multiple chords match, they will all have the same Root, but will 
vary in Size and therefore Quality (V of c major could be g major triad 
or g dominant seven).

<P><VAR>QualifiedFunction</VAR> is in the form [[RomanNumeralList],Key], 
where Key is of the form [Chroma,Mode], as in <A class="pred" href="theory.html#function/1">function/1</A>.

<P>in sequential applications, the tonic mode is assumed constant 
('major' in the example).

<P>ex:

<PRE class="code">
function( [[[c, ''], [e, ''], [g, ''], [b, '']],    [c, ''], major, seven],  [            [],[[c,''],major]]  ).
function( [[[g, ''], [b, ''], [d, '']],             [g, ''], major, triad],  [         ['V'],[[c,''],major]]  ).
function( [[[d, ''], [f, #], [a, '']],              [d, ''], major, triad],  [     ['V','V'],[[c,''],major]]  ).
function( [[[e, ''], [g, ''], [b, ''], [d, '']],    [e, ''], minor, seven],  [['II','V','V'],[[c,''],major]]  ).

% we currently disallow 'I' functions so we don't clutter our applied function list with identities.  see first example above and functor/1.
function( X,                                                                          [['I'],[[c,''],major]]  ).  %fails.
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chord</VAR> </TD><TD>a chord in the form 
[ChromaSet, Root, Quality, Size], ala <A class="pred" href="theory.html#chordChromaSet/4">chordChromaSet/4</A> </TD></TR>
<TR VALIGN=top><TD><VAR>QualifiedFunction</VAR> </TD><TD>a function in 
the form [[RomanNumeralList],Key], with Key of form [Chroma,Mode], ala <A class="pred" href="theory.html#function/1">function/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="simplifyFunction/2"><STRONG>simplifyFunction</STRONG>(<VAR>?QualifiedFunction, 
?SimplestFunction</VAR>)</A></DT>
<DD class="defbody">
eliminate (add) applied functions from (to) a qualified function

<P><VAR>QualifiedFunction</VAR> is in the form [[RomanNumeralList],Key], 
where Key is of the form [Chroma,Mode], as in <A class="pred" href="theory.html#function/1">function/1</A>.

<P><VAR>SimplestFunction</VAR> is in the same form and is the simplest 
equivalent non-tonic function.

<P>for example, II/V/V/c major is e minor. this is a complicated applied 
function. the simplest function of e minor (aside from the trivial tonic 
of e minor) is the II of d major.

<P>ex:

<PRE class="code">
simplifyFunction([['II','V','V'],[[c,''],major]],[['II'], [[d, ''], major]]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>QualifiedFunction</VAR> </TD><TD>a function in 
the form [[RomanNumeralList],Key], with Key of form [Chroma,Mode], ala <A class="pred" href="theory.html#function/1">function/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>SimplestFunction</VAR> </TD><TD>a function in 
the same form, but with no application levels. tonics are trivially 
excluded. </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="cumsum/2"><STRONG>cumsum</STRONG>(<VAR>+List:numbers, 
?Sums:numbers</VAR>)</A></DT>
<DD class="defbody">
cumulative sum

<P>ex:

<PRE class="code">
cumsum([1, 2, 3],[1,3,6]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>List</VAR> </TD><TD><VAR>List</VAR> of numbers </TD></TR>
<TR VALIGN=top><TD><VAR>Sums</VAR> </TD><TD><VAR>List</VAR> of numbers 
that is the cumulative sum of <VAR>List</VAR> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="conforms/2"><STRONG>conforms</STRONG>(<VAR>+Sample, 
+ClassList</VAR>)</A></DT>
<DD class="defbody">
check conformation to a <VAR>ClassList</VAR>

<P>class lists are lists of items each of the form functor(List), where 
functor is a requirement class (atLeast1, exactly1, or optional), and 
List is a list of items

<P>ex:

<PRE class="code">
conforms([a,d,f],  [atLeast1([b,a]),exactly1([g,h,f]),optional([q,e]),atLeast1([d])]).
conforms([a,d,f,w],[atLeast1([b,a]),exactly1([g,h,f]),optional([q,e]),atLeast1([d])]). % fails -- ClassList does not allow any 'w'
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Sample</VAR> </TD><TD>a list of items that fit 
the constraints in <VAR>ClassList</VAR> </TD></TR>
<TR VALIGN=top><TD><VAR>ClassList</VAR> </TD><TD>a list of items each of 
the form functor(List), where functor is a requirement class (atLeast1, 
exactly1, or optional), and List is a list of items </TD></TR>
</TABLE>

<DL>
<DT><B>bug</B><DD> this does not enforce minimum requirements! consider 
merging with <A class="pred" href="theory.html#generate/3">generate/3</A> 
-- no one calls this anyway

<PRE class="code">
theory:  ?- conforms([a,b,d,f,b],[atLeast1([b,a]),exactly1([g,h,f]),optional([q,e]),atLeast1([d])]).
true.

theory:  ?- conforms([a,b,d,b],[atLeast1([b,a]),exactly1([g,h,f]),optional([q,e]),atLeast1([d])]).
true.

theory:  ?- conforms([a,b,b],[atLeast1([b,a]),exactly1([g,h,f]),optional([q,e]),atLeast1([d])]).
true.

theory:  ?- conforms([],[atLeast1([b,a]),exactly1([g,h,f]),optional([q,e]),atLeast1([d])]).
true.
</PRE>

</DL>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="generate/3"><STRONG>generate</STRONG>(<VAR>-Sample, 
+ClassList, +Len</VAR>)</A></DT>
<DD class="defbody">
generate all possible Samples that conform to a <VAR>ClassList</VAR> and 
Length

<P>class lists are lists of items each of the form functor(List), where 
functor is a requirement class (atLeast1, exactly1, or optional), and 
List is a list of items

<P>does not make every permutation (would need to in order to replace <A class="pred" href="theory.html#conforms/2">conforms/2</A>) 
-- it does repeat some due to optional items after the minimum 
requirements have been satisfied.

<P>ex:

<PRE class="code">
theory:  ?- generate(X,[atLeast1([b,a]),exactly1([g,h,f]),optional([q,e]),atLeast1([d])],4).
X = [b, b, d, g] ;
X = [a, b, d, g] ;
X = [b, d, g, q] ;
X = [b, d, e, g] ;
X = [b, d, d, g] ;
X = [b, b, d, h] ;
X = [a, b, d, h] ;
X = [b, d, h, q] ;
X = [b, d, e, h] ;
X = [b, d, d, h] ;
X = [b, b, d, f] ;
X = [a, b, d, f] ;
X = [b, d, f, q] ;
X = [b, d, e, f] ;
X = [b, d, d, f] ;
X = [a, b, d, g] ;
X = [a, a, d, g] ;
X = [a, d, g, q] ;
X = [a, d, e, g] ;
X = [a, d, d, g] ;
X = [a, b, d, h] ;
X = [a, a, d, h] ;
X = [a, d, h, q] ;
X = [a, d, e, h] ;
X = [a, d, d, h] ;
X = [a, b, d, f] ;
X = [a, a, d, f] ;
X = [a, d, f, q] ;
X = [a, d, e, f] ;
X = [a, d, d, f] ;
false.
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Sample</VAR> </TD><TD>a list of items that fit 
the constraints in <VAR>ClassList</VAR> </TD></TR>
<TR VALIGN=top><TD><VAR>ClassList</VAR> </TD><TD>a list of items each of 
the form functor(List), where functor is a requirement class (atLeast1, 
exactly1, or optional), and List is a list of items </TD></TR>
<TR VALIGN=top><TD><VAR>Len</VAR> </TD><TD>length of <VAR>Sample</VAR> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="accidental/2"><STRONG>accidental</STRONG>(<VAR>?Name, 
?HalfStepsUpFromNatural</VAR>)</A></DT>
<DD class="defbody">
find accidental inflections

<P>ex:

<PRE class="code">
accidental(bb, -2).
accidental(b, -1).
accidental('', 0).
accidental(#, 1).
accidental(x, 2).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Name</VAR> </TD><TD>one of the accidentals in <A class="pred" href="theory.html#accidentals/1">accidentals/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>HalfStepsUpFromNatural</VAR> </TD><TD>the 
corresponding number of half steps up from natural </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="whiteKey/2"><STRONG>whiteKey</STRONG>(<VAR>?Name, 
?HalfStepsUpFromFirstWhiteKey</VAR>)</A></DT>
<DD class="defbody">
find white key positions

<P>ex:

<PRE class="code">
whiteKey(d,5).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Name</VAR> </TD><TD>one of the whiteKeys in <A class="pred" href="theory.html#whiteKeys/1">whiteKeys/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>HalfStepsUpFromFirstWhiteKey</VAR> </TD><TD>the 
corresponding number of half steps up from the first whiteKey in <A class="pred" href="theory.html#whiteKeys/1">whiteKeys/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chroma/1"><STRONG>chroma</STRONG>(<VAR>?Chroma</VAR>)</A></DT>
<DD class="defbody">
chromas are of the form [WhiteKey,Accidental]

<P>ex:

<PRE class="code">
chroma([a,#]).
chroma([b,'']). % natural
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chroma</VAR> </TD><TD><VAR>Chroma</VAR> in the 
form [WhiteKey,Accidental], where WhiteKey is ala <A class="pred" href="theory.html#whiteKey/2">whiteKey/2</A> 
and Accidental is ala <A class="pred" href="theory.html#accidentals/1">accidentals/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="octaveRange/2"><STRONG>octaveRange</STRONG>(<VAR>?Lo, 
?Hi</VAR>)</A></DT>
<DD class="defbody">
the octave range of the defined voices

<P>the defined voice ranges limit what we consider acceptable octave 
numbers, and therefore keeps the domain of notes finite.

<P>ex:

<PRE class="code">
octaveRange(1,5).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Lo</VAR> </TD><TD>lowest octave num defined by a 
voice </TD></TR>
<TR VALIGN=top><TD><VAR>Hi</VAR> </TD><TD>highest octave num defined by 
a voice </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="note/1"><STRONG>note</STRONG>(<VAR>?Note</VAR>)</A></DT>
<DD class="defbody">
notes have the form [[Chroma],OctaveNumber]

<P>notice the octave breaks convention in <A class="pred" href="theory.html#octaveBreaks/1">octaveBreaks/1</A>

<P>ex:

<PRE class="code">
note([[b, bb], 4]). % b-double-flat
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Note</VAR> </TD><TD>a note of the form 
[[Chroma],OctaveNumber], where Chroma is ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> 
and OctaveNumber is within OctaveRange/2 </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="noteNum/2"><STRONG>noteNum</STRONG>(<VAR>?Note, 
?N</VAR>)</A></DT>
<DD class="defbody">
find the MIDI note number of a note

<P>the range of noteNums is limited by the octave range of the voices 
defined by <A class="pred" href="theory.html#voice/3">voice/3</A>

<P>notice the octave breaks convention in <A class="pred" href="theory.html#octaveBreaks/1">octaveBreaks/1</A>

<P>ex:

<PRE class="code">
noteNum([[a, bb], 1],43).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Note</VAR> </TD><TD>a note of the form 
[[Chroma],OctaveNumber] ala <A class="pred" href="theory.html#note/1">note/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>N</VAR> </TD><TD>the MIDI note numer </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="intervalQuality/3"><STRONG>intervalQuality</STRONG>(<VAR>?Quality, 
?N, ?Type</VAR>)</A></DT>
<DD class="defbody">
defines how intervals of perfect and imperfect types are modified by 
qualities

<P>ex:

<PRE class="code">
intervalQuality(augmented, 1, imperfect).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Quality</VAR> </TD><TD>as in <A class="pred" href="theory.html#intervalQualities/2">intervalQualities/2</A> </TD></TR>
<TR VALIGN=top><TD><VAR>N</VAR> </TD><TD>the number of half steps away 
from perfect or major </TD></TR>
<TR VALIGN=top><TD><VAR>Type</VAR> </TD><TD>as in <A class="pred" href="theory.html#intervalNamesTypes/1">intervalNamesTypes/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="interval/1"><STRONG>interval</STRONG>(<VAR>?Interval</VAR>)</A></DT>
<DD class="defbody">
Intervals are [Quality,Degree]

<P>ex:

<PRE class="code">
interval([major, third]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Interval</VAR> </TD><TD>in the form 
[Quality,Degree], where Qualities and Degrees are as defined in <A class="pred" href="theory.html#intervalQualities/2">intervalQualities/2</A> 
and <A class="pred" href="theory.html#intervalNamesTypes/1">intervalNamesTypes/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="interval/4"><STRONG>interval</STRONG>(<VAR>?Chroma1, 
?Chroma2, ?Interval, ?HalfSteps</VAR>)</A></DT>
<DD class="defbody">
find the ascending <VAR>Interval</VAR> from <VAR>Chroma1</VAR> UP to <VAR>Chroma2</VAR> 
and the associated number of <VAR>HalfSteps</VAR>

<P>ex:

<PRE class="code">
interval([a, ''], [f, ''], [minor, sixth], 8).
interval([c,''],[b,x],A,B). % fails - there is no such thing as a double augmented seventh
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chroma1</VAR> </TD><TD>a chroma </TD></TR>
<TR VALIGN=top><TD><VAR>Chroma2</VAR> </TD><TD>a chroma </TD></TR>
<TR VALIGN=top><TD><VAR>Interval</VAR> </TD><TD>the interval from <VAR>Chroma1</VAR> 
UP to <VAR>Chroma2</VAR> in the form [Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>HalfSteps</VAR> </TD><TD>the associated number 
of <VAR>HalfSteps</VAR> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="interval/2"><STRONG>interval</STRONG>(<VAR>?Interval, 
?HalfSteps</VAR>)</A></DT>
<DD class="defbody">
find the number of <VAR>HalfSteps</VAR> associated with an <VAR>Interval</VAR>

<P>ex:

<PRE class="code">
Interval([minor, seventh], 10).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Interval</VAR> </TD><TD>an interval of the form 
[Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>HalfSteps</VAR> </TD><TD>the associated number 
of <VAR>HalfSteps</VAR> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="interval/3"><STRONG>interval</STRONG>(<VAR>?Chroma1, 
?Chroma2, ?Interval</VAR>)</A></DT>
<DD class="defbody">
find the ascending <VAR>Interval</VAR> from <VAR>Chroma1</VAR> UP to <VAR>Chroma2</VAR>

<P>ex:

<PRE class="code">
interval([e, ''], [f, #], [major, second]).
interval([c,''],[b,x], X). % fails - there is no such thing as a double augmented seventh
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Chroma1</VAR> </TD><TD>a chroma, ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Chroma2</VAR> </TD><TD>a chroma, ala <A class="pred" href="theory.html#chroma/1">chroma/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Interval</VAR> </TD><TD>the interval from <VAR>Chroma1</VAR> 
UP to <VAR>Chroma2</VAR> in the form [Quality,Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="intervalSize/2"><STRONG>intervalSize</STRONG>(<VAR>?Interval, 
?Spec</VAR>)</A></DT>
<DD class="defbody">
determine degree and size of an interval

<P>ex:

<PRE class="code">
intervalSize([minor, third], (3, 2)).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Interval</VAR> </TD><TD>an interval of the form 
[Quality, Degree] ala <A class="pred" href="theory.html#interval/1">interval/1</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Spec</VAR> </TD><TD>a tuple of the form 
(HalfSteps,DegreeIndex), where HalfSteps describes <VAR>Interval</VAR>'s 
size and DegreeIndex is the 0-based position of Degree in <A class="pred" href="theory.html#intervalNamesTypes/1">intervalNamesTypes/1</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chordChromaClasses/4"><STRONG>chordChromaClasses</STRONG>(<VAR>-ClassList, 
?Root, ?Quality, ?Size</VAR>)</A></DT>
<DD class="defbody">
find chromaClasses for chord of <VAR>Root</VAR>, <VAR>Quality</VAR>, <VAR>Size</VAR>

<P>chromaClasses enforce the doubling rules specified in <A class="pred" href="theory.html#selectVoicing/1">selectVoicing/1</A>

<P>at least one root and one third, perfect fifths optional, exactly one 
seventh and altered fifth when present (dissonances over <VAR>Root</VAR> 
not doubled)

<P>need to update to prevent R333, RR33, and R337, ie strictly more 
roots than anything else when fifth omitted (R335 and R355 OK)

<P>ex:

<PRE class="code">
chordChromaClasses([atLeast1([[f, #]]), atLeast1([[a, '']]), exactly1([[c, '']]), exactly1([[e, '']])], [f, #], halfdiminished, seven).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>ClassList</VAR> </TD><TD>a list of 
chromaClasses, each of the form functor(ChromaList), where functor is 
the requirement class (atLeast1, exactly1, or optional), and ChromaList 
is a list of chromas </TD></TR>
<TR VALIGN=top><TD><VAR>Root</VAR> </TD><TD>a chroma as in second 
argument of <A class="pred" href="theory.html#chord/4">chord/4</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Quality</VAR> </TD><TD>as in third argument of <A class="pred" href="theory.html#chord/4">chord/4</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Size</VAR> </TD><TD>as in fourth argument of <A class="pred" href="theory.html#chord/4">chord/4</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chordChromaSet/4"><STRONG>chordChromaSet</STRONG>(<VAR>-ChromaSet, 
?Root, ?Quality, ?Size</VAR>)</A></DT>
<DD class="defbody">
find chromas for chord of <VAR>Root</VAR>, <VAR>Quality</VAR>, <VAR>Size</VAR>

<P>ex:

<PRE class="code">
chordChromaSet([[d, b], [f, ''], [a, '']],[d,b],augmented,triad).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>ChromaSet</VAR> </TD><TD>the list of chromas in 
the chord specified by <VAR>Root</VAR>, <VAR>Quality</VAR>, <VAR>Size</VAR>, 
without dupes, and ordered by degree </TD></TR>
<TR VALIGN=top><TD><VAR>Root</VAR> </TD><TD>a chroma as in second 
argument of <A class="pred" href="theory.html#chord/4">chord/4</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Quality</VAR> </TD><TD>as in third argument of <A class="pred" href="theory.html#chord/4">chord/4</A> </TD></TR>
<TR VALIGN=top><TD><VAR>Size</VAR> </TD><TD>as in fourth argument of <A class="pred" href="theory.html#chord/4">chord/4</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="chordNoteNums/2"><STRONG>chordNoteNums</STRONG>(<VAR>-NumList, 
?Chord</VAR>)</A></DT>
<DD class="defbody">
find noteClasses for <VAR>Chord</VAR>

<P>these are octave blowouts of the chromas defined in <A class="pred" href="theory.html#chordChromaClasses/4">chordChromaClasses/4</A>

<P>ex:

<PRE class="code">
chordNoteNums(A,[[g,x],halfdiminished,seven]),maplist(writeln,A).
atLeast1([45-[[g, x], 1], 57-[[g, x], 2], 69-[[g, x], 3], 81-[[g, x], 4], 93-[[g, x], 5]])
atLeast1([48-[[b, #], 1], 60-[[b, #], 2], 72-[[b, #], 3], 84-[[b, #], 4], 96-[[b, #], 5]])
exactly1([39-[[d, #], 1], 51-[[d, #], 2], 63-[[d, #], 3], 75-[[d, #], 4], 87-[[d, #], 5]])
exactly1([43-[[f, x], 1], 55-[[f, x], 2], 67-[[f, x], 3], 79-[[f, x], 4], 91-[[f, x], 5]])
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>NumList</VAR> </TD><TD>a list of noteClasses, 
each of the form functor(NotePairList), where functor is the requirement 
class (atLeast1, exactly1, or optional), and NotePairList is a list of 
pairs NoteNum-Note </TD></TR>
<TR VALIGN=top><TD><VAR>Chord</VAR> </TD><TD>in form [Root, Quality, 
Size], ala last three arguments of <A class="pred" href="theory.html#chord/4">chord/4</A> </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[det]</span><A NAME="ranges/1"><STRONG>ranges</STRONG>(<VAR>?Ranges</VAR>)</A></DT>
<DD class="defbody">
list of voice ranges

<P>ex:

<PRE class="code">
ranges([[40, 55], [48, 67], [55, 72], [60, 84]]).
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Ranges</VAR> </TD><TD>list of [NoteNum, NoteNum] 
ranges, one for each voice, sorted first on low extreme </TD></TR>
</TABLE>

</DD>
<DT class="pubdef"><span class="pred-tag">[multi]</span><A NAME="selectVoicing/1"><STRONG>selectVoicing</STRONG>(<VAR>?Voicing</VAR>)</A></DT>
<DD class="defbody">
generate legal voicings in a random order without repeats

<P>each time you call selectVoicing, you get a generator of all legal 
chord voicings, without repeats, in a new random order. voicings are 
precached for fast lookup.

<P>if <VAR>Voicing</VAR> is totally uninstantiated, there are about 20k 
legal voicings

<P>voicing rules:

<P>
<UL>
<LI>Notes are all chord tones of a chord and (Notes,Root,Quality,Size) 
satisfy the requirements in <A class="pred" href="theory.html#chordChromaClasses/4">chordChromaClasses/4</A> 
(at least one root and one third, perfect fifths optional, exactly one 
seventh and altered fifth when present)
<LI>dissonances over Root and Bass not doubled

<P>
<UL>
<LI>need to update to prevent R333, RR33, and R337, ie strictly more 
roots than anything else when fifth omitted (R335 and R355 OK)
</UL>

<P>
<LI>one note for each voice defined by <A class="pred" href="theory.html#voice/3">voice/3</A>, 
in the specified range, without overlap (unison OK. aldwell schacter and 
roig-francoli both suggest that brief crossing can be acceptable in 
inner voices, we may relax this constraint.).
<LI>at most one octave between adjacent voices (2 octaves may separate 
the bottom 2 voices)
</UL>

<P>ex:

<PRE class="code">
selectVoicing([A,[c,''],dominant,seven,second]).

A = [[[g, ''], 1], [[c, ''], 2], [[b, b], 2], [[e, ''], 3]] ;
A = [[[g, ''], 1], [[e, ''], 2], [[b, b], 2], [[c, ''], 3]] ;
A = [[[g, ''], 1], [[e, ''], 2], [[c, ''], 3], [[b, b], 3]] ;
A = [[[g, ''], 1], [[b, b], 2], [[c, ''], 3], [[e, ''], 3]] ;
A = [[[g, ''], 2], [[b, b], 2], [[c, ''], 3], [[e, ''], 3]] ;
A = [[[g, ''], 1], [[c, ''], 3], [[e, ''], 3], [[b, b], 3]] ;
A = [[[g, ''], 2], [[c, ''], 3], [[e, ''], 3], [[b, b], 3]] ;
A = [[[g, ''], 1], [[c, ''], 3], [[b, b], 3], [[e, ''], 4]] ;
A = [[[g, ''], 2], [[c, ''], 3], [[b, b], 3], [[e, ''], 4]] ;
A = [[[g, ''], 1], [[b, b], 2], [[e, ''], 3], [[c, ''], 4]] ;
A = [[[g, ''], 2], [[b, b], 2], [[e, ''], 3], [[c, ''], 4]] ;
A = [[[g, ''], 1], [[e, ''], 3], [[b, b], 3], [[c, ''], 4]] ;
A = [[[g, ''], 2], [[e, ''], 3], [[b, b], 3], [[c, ''], 4]] ;
A = [[[g, ''], 1], [[e, ''], 3], [[c, ''], 4], [[b, b], 4]] ;
A = [[[g, ''], 2], [[e, ''], 3], [[c, ''], 4], [[b, b], 4]] ;
false.
</PRE>

<TABLE class="paramlist">
<TR VALIGN=top><TD><VAR>Voicing</VAR> </TD><TD>in form 
[Notes,Root,Quality,Size,Inversion], where Notes are ordered by 
noteNum/voice, Root, Quality, and Size are as in the last three 
arguments of <A class="pred" href="theory.html#chord/4">chord/4</A>, and 
Inversion is as the first arg in <A class="pred" href="theory.html#chordInversion/2">chordInversion/2</A> </TD></TR>
</TABLE>

</DD>
</DL>

<P></BODY></HTML>